iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 22
1
自我挑戰組

Wordpress 外掛開發系列 第 22

「Wordpress 外掛開發」刻個字就要給一百五十元,加上你的動態價格變化

  • 分享至 

  • xImage
  •  

我們接觸著昨天的尾端,我們做了能夠碰到了價格的hook,再次抱怨wooCommerce的docs真的是很不友善,我們使用的價錢的功能,要在我們使用的地方告一個段落,接著我們今天的目標就是將前端顯示的價格,與進到購物車的後端價格做一個確切的變化與更正,而並且在最後加入到購物車中,這樣就可以小小的動態調整價錢功能啦!而對了,我們的外掛的模板是參考WooCommerce Dynamic Pricing來的,價格很驚人,不過可以省你很多時間去開發這個,這個項目是真的滿複雜的!

處理前端的價格變化

我們現在在我們的產品頁面中加入新的action,來專門處理我們計算前端的價格,並且撰寫Javscript來處理價格的置換,而我們這邊使用的價錢,並不會直接進到後端,我們的後端為了安全性問題,我們仍然使用當下的參數來做第二次得價錢計算,而在目前這裡,我們會取代顯示的價錢,但是價錢在進到點擊submit時,仍然是以我們當初輸入的價錢。


add_action('init','go_ranger_wc_init');

function go_ranger_wc_init(){
	wp_register_script(
			'go-ranger-calculator',      
			plugin_dir_url( __FILE__ ) . '/post.js',
			array(),                                  
			'1.0.0',                                  
			true                                      
	);
}

add_action('woocommerce_before_add_to_cart_form','go_ranger_variation');

 function go_ranger_variation(){
	wp_enqueue_script( 'go-ranger-calculator' );
	 global $product;
	 $show_content = $product->get_meta('go_ranger_enrave');
	 if($show_content){
		?>
		<style> 
		.price{
			display:none;
		}
		.price.go-ranger-price{
			display:block;
		}
		</style>
		<div class="go-ranger-flex" style="display:flex;justify-content:space-around;align-items:center;">
			<span>刻字在這,加些錢錢</span>
			<input type="text" data-go-ranger-name="engrave" id="go_ranger_engrave">
		</div>
		<p class="price go-ranger-price">
			<span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">$</span><span class="go-ranger-price-tag">990</span></bdi></span>
		</p>
		<?php
	 }
	 
 }
window.onload = function () {
  let go_ranger_engrave = document.getElementById('go_ranger_engrave');
  let price_tag = document.getElementsByClassName('go-ranger-price-tag')[0];

  go_ranger_engrave.addEventListener('change', function (event) {
    // 在這裡拿到
  })
}

那我們目前就已經有了將正常的價格隱藏,並且顯示出我們做出來的模擬價格,而如果你的目的是要做會員登入才使用購物車,又要十足弔胃口的話,應該是要由可以購買的hook與新增新的價格的action動手做,這裡如果加上限定role才可以購買這類的功能,是滿熱門的操作手法。
https://ithelp.ithome.com.tw/upload/images/20201006/20104531MLt5DDfgQY.jpg

開始計算價格

那我們開始,先將正常的價格放上,並且撰寫js的邏輯來計算我們的刻字服務,假如沒有字則不需要多收費,如果有則是一百五十元,那我們使用wc_get_price_to_display來取得我們的價錢,並且寫入預設的價錢,並且使用localize的功能,將我們這邊需要取得的參數帶入js之中。

$price = wc_get_price_to_display($product);
wp_enqueue_script( 'go-ranger-calculator' );
wp_localize_script( 
  'go-ranger-calculator' ,
  'go_ranger_object',
  array(
    'ajaxurl' => admin_url( 'admin-ajax.php' ),
    'price' => $price
  ) );
.
.
.
	<p class="price go-ranger-price">
			<span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">$</span><span class="go-ranger-price-tag"><?php echo $price; ?></span></bdi></span>
		</p>
window.onload = function () {
  const DISPLAY_PRICE = go_ranger_object.price;
  let go_ranger_engrave = document.getElementById('go_ranger_engrave');
  let price_tag = document.getElementsByClassName('go-ranger-price-tag')[0];

  go_ranger_engrave.addEventListener('change', function (event) {
    let change_context = this.value.match(/a-zA-Z0-9/);
    if (change_context) {
      r_sir_change_price(price_tag);
    } else r_sir_replace_price_tag(price_tag, DISPLAY_PRICE);
  })
}

function r_sir_change_price(price_tag) {
  target_price = DISPLAY_PRICE + 150;
  r_sir_replace_price_tag(price_tag, target_price);
}

function r_sir_replace_price_tag(target_tag, target_price) {
  target_tag.innerHTML = target_price;
}

加入字串價格

我們現在在我們的產品頁面中加入第二個的action,我們的前端價格計算,就暴露在js前面,是有可能被打破的,所以不要傻呼呼的像當初某家購物網站,直接把前端的價錢送到後端都不做比對,我們在進到後端,是直接呼叫woocommerce_add_to_cart來對加入購物車的價格做驗證,而我們在這邊可以再多掛一個新的價格,來做到更好的延伸。

 add_action('woocommerce_add_to_cart', 'go_ranger_callback', 20, 6);

function go_ranger_callback($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data){
	global $woocommerce;
	
	foreach(WC()->cart->get_cart() as $cart_item_key => $values){
		$cartItemPrice		= $values['data']->get_price();
		$values['data']->set_price(calculator_set_price($cartItemPrice,$cart_item_data,$quantity));
	}
}

function calculator_set_price($cartItemPrice,$cart_item_data,$quantity){
	$cart_item_data->get_meta('go_ranger_engrave');
	if(!empty($cart_item_data))	return ($cartItemPrice + 150 ) * $quantity;
	
	return $cartItemPrice * $quantity;
}

https://ithelp.ithome.com.tw/upload/images/20201006/20104531e4VRRtjuxD.jpg

這樣價格進到購物車後,就會是正確的價格,而這個外掛的可能性,無非加入更多複雜的價格公式,而在公式的計算理想是建立class來專門處理這些模擬出來的價錢並且推算,並且有下列幾種的helper,能夠更加的完整。

priceHelper

來處理所有的價格轉換,並且還有ajax callback這一些地係向,並且將我們有提供到的模擬價格部分,都是由這個class來建立並輸出。

templateHelper

在每個頁面之中,你不可能只使用原生的延伸,更有可能是需要建立自己的購物欄位,或是特別的loop。

adminHelper

你在自己的外掛,總會有自己的後台頁面,但是在這種比較高複雜的部分之中,一個基本的class能夠涵蓋是對於維護與後續發展又更好的幫助的,比如說再動用到option API的時候,更可以有自己的handler來處理。

orderHelper

而我們的訂單總會有一些meta需要產生,而有時簡單有時就複雜,有時候你可能得將meta的輸出有模板的輸出,並且在出invoice或是reciept可以有更好的支援,這個在很多外掛都會有類似的應用,雖然名稱可能不叫這個,但是功能類似。

ProductHelper

最後,這是你要將產品的加入的項目,寫入的公式,是否開啟,又有什麼特殊的需求,比如說一個然在限購或是產品本身打五折,但是多的服務是沒有折扣的這些比較實際面的應用。

roleHelper

我們可以做一個專門處理role與折扣的,因為折扣的公式並不單純,所以他是可以與priceHelper做一個很好的相依,在正確的role上做出正確的折扣。

最後,這一個簡單的應用,如果是使用ajax callback,並且回到產品頁面來做,應該可以免於價格更改時候刻意改動數字,這東西寫著寫著發現也是不少類似的外掛可以參考,不過都是要收錢的啦XD 我總覺得自己沒有找到一直能動態更改order價錢的hook,這樣的做法是太過於粗糙,如果往後有新的發現,我會繼續在其他地方把這個小外掛給發表出去。

明天我們來講講外掛開發後,總不能射後不理吧,該如何維護等等的注意事項,而在講完後,我預計繼續來做WooCommerce - Nested Category Layout,看到這個價錢很驚人,不知道是否除了加入模板與loop之餘,還有什麼地方是需要去注意的,否則怎麼可以有這麼貴的價格XD

reference

WC-Product
WooCommerce Visual Hook Guide: Single Product Page
how to use ajax in wiordpress
wbe design industry jargon glossary and resources


上一篇
「Wordpress 外掛開發」為大爺們,加上特別的折價服務
下一篇
「Wordpress 外掛開發」寫完外掛後,然後呢?
系列文
Wordpress 外掛開發30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言